package cn.cs.message.tempstorage.disk;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.cs.message.Message;
import cn.cs.message.tempstorage.AbstractTempStorage;
import cn.cs.message.tempstorage.TempStorage;
/**实现一个磁盘的,记录暂存在磁盘**/
public class DiskTempStorage extends AbstractTempStorage 
{
	private static final Logger logger=LoggerFactory.getLogger(DiskTempStorage.class);
	private static final String DIR_NAME="tempStorage";
	public static final String FILE_SUFFIX=".rmsg";
	
	/**暂存记录文件的路径*/
	private static String path=Thread.currentThread().getContextClassLoader().getResource("").getPath()+DIR_NAME;;
	
	/**历史暂存记录的文件集合*/
	private List<File> history;
	/**暂存记录Reader*/
	private DiskTempStorageIterator iterator;
	
	/**多线程写记录*/
	private Map<Thread,DiskWriter> diskWriterMap=new ConcurrentHashMap<Thread, DiskWriter>();
	
	/**记录暂存消息个数*/
	private AtomicLong count=new AtomicLong();
	
	@Override
	public void add(Message msg) 
	{
		Thread thread=Thread.currentThread();
		DiskWriter diskWriter=diskWriterMap.get(thread);
		if(diskWriter==null)
		{
			diskWriter=new DiskWriter(path);
			diskWriterMap.put(thread, diskWriter);
		}
		if(!diskWriter.write(msg))
		{
			logger.error("发生严重错误，请查看相关应用");
			if(listener!=null)
				listener.onError("发生严重错误，请查看相关应用");
		}
		if(listener!=null)
			listener.onIncreaseMsg(count.incrementAndGet());
	}
	
	public void init()
	{
		File pathFile=new File(path);
		if(!pathFile.exists())
			pathFile.mkdir();
		
		//加载历史暂存记录的文件集合
		File[] files=pathFile.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith(FILE_SUFFIX);
			}
		});
		if(files==null)
			history=Collections.EMPTY_LIST;
		else
			history=Arrays.asList(files);
		
		//初始化iterator
		iterator=new DiskTempStorageIterator(history.iterator());
	}
	public DiskTempStorage(){}
	private DiskTempStorage(DiskTempStorageIterator iterator)
	{
		this.iterator=iterator;
	}
	
	@Override
	public TempStorage newTempStorage()
	{
		TempStorage tempStorage=new DiskTempStorage(new DiskTempStorageIterator(null));
		tempStorage.setListener(listener);
		//更换暂存器，要把DiskReader的数据来源换成workSpace
		history=new ArrayList<File>();
		for(DiskWriter writer:diskWriterMap.values())
		{
			history.addAll(writer.getFiles());
			writer.stop();
		}
		iterator.setFiles(history.iterator());
		logger.info("#########################切换暂存器##############################");
		return tempStorage;
	}
	
	@Override
	public boolean hasMsg()
	{
		return count.get()>0||(history!=null&&history.size()>0);		
	}

	@Override
	public long size()
	{
		return count.get();
	}
	
	@Override
	public void clear() 
	{
		//清空diskReader关联的文件集合
		diskWriterMap.clear();
		if(history==null)
			return;
		boolean res;
		for(File file:history)
		{
			do{
				System.gc();
				res=file.delete();
				logger.info("#############################删除文件："+res+"======"+file.getName());
			}while(!res);
		}
		history=null;
		logger.info("################################清理了"+iterator.getCount()+"个消息");
	}

	@Override
	public Iterator<Message> iterator() 
	{
		return iterator;
	}
	
}
